// CPage8_MasterLevels.cpp : Implementierungsdatei
//

#include "stdafx.h"
#include "Charplan.h"
#include "CPage8_MasterLevels.h"
#include "Charplandoc.h"


#define NOF_MASTERS 2



#define COLOR_FOR_SOLO  RGB(255,255,170)
#define COLOR_FOR_GROUP  RGB(170,255,170)
#define COLOR_FOR_BG  RGB(255,255,255)


// CPage8_MasterLevels-Dialogfeld

IMPLEMENT_DYNAMIC(CPage8_MasterLevels, CAPage)
CPage8_MasterLevels::CPage8_MasterLevels(CWnd* pParent /*=NULL*/)
        : CAPage(CPage8_MasterLevels::IDD, pParent)
{
    mb_internal_selection = false;
}

CPage8_MasterLevels::~CPage8_MasterLevels()
{
}

void CPage8_MasterLevels::DoDataExchange(CDataExchange* pDX)
{
    CAPage::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT1, mwnd_track_title[0]);
    DDX_Control(pDX, IDC_EDIT2, mwnd_track_title[1]);
    DDX_Control(pDX, IDC_LIST3, mwnd_list[0]);
    DDX_Control(pDX, IDC_LIST1, mwnd_list[1]);
    DDX_Control(pDX, IDC_BUTTON1, mwnd_selectbutton);
    DDX_Control(pDX, IDC_EDIT3, mwnd_description);
    DDX_Control(pDX, IDC_LIST2, mwnd_masterquests);
    DDX_Control(pDX, IDC_LIST4, mwnd_masterlevels);
}


BEGIN_MESSAGE_MAP(CPage8_MasterLevels, CAPage)
    ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
    ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST3, OnNMCustomdrawList1)
    ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, OnNMCustomdrawList1)
    ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST2, OnColumnClick)
    ON_REGISTERED_MESSAGE(WM_XLISTCTRL_CHECKBOX_CLICKED, OnCheckbox)
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST4, &CPage8_MasterLevels::OnLvnItemchangedList4)
    ON_WM_DESTROY()
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST3, &CPage8_MasterLevels::OnLvnItemchangedList3)
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPage8_MasterLevels::OnLvnItemchangedList1)
END_MESSAGE_MAP()




// CPage8_MasterLevels-Meldungshandler
void CPage8_MasterLevels::SetupToolTips()
{
    CAPage::SetupToolTips();

    // Abilities
// mToolTips.AddTool(&mwnd_list1,CString(""));
// mToolTips.AddTool(&mwnd_list2,CString(""));

    // Basic UI
    mToolTips.AddTool(&mwnd_selectbutton, _T("Select Master-Track you which"));
}




//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::UpdateMasterLevelsRects(int level)
{
    int idx = 0;
    for (;idx<mwnd_masterlevels.GetItemCount();idx++)
        if (mwnd_masterlevels.GetItemData(idx)==level) break;

    ASSERT(idx<mwnd_masterlevels.GetItemCount());
    if (idx>=mwnd_masterlevels.GetItemCount()) return;


    CStringArray ma_names;
    IntArray ma_types;

    gdbinterface.GetMasterQuests(level,ma_names,ma_types);
    DWORD quest = GetDocument()->GetMasterQuests(level);

    mwnd_masterlevels.SetColorRectMax(idx,1,(int)ma_names.GetCount());

    for (int t=0;t<ma_names.GetCount();t++)
    {
        COLORREF col = RGB(255,255,255);

        if (0!=(quest&(1<<(t+1)))) col = RGB(64,64,255);
        else
        {
            switch (ma_types[t])
            {
                case 0: col = COLOR_FOR_SOLO; break;
                case 1: col = COLOR_FOR_GROUP; break;
                case 2: col = COLOR_FOR_BG; break;
                default:
                    ASSERT(false);
            }
        }

        if (quest&1)
        {
            col = RGB((GetRValue(col)+0)/2 , (GetGValue(col)+0)/2 , (GetBValue(col)+0)/2);
        }

        mwnd_masterlevels.SetColorRect(idx,1,t,col);
        mwnd_masterlevels.SetCheckbox(idx, 0, (quest&1));

    }

}


//////////////////////////////////////////////////////////////////////////
BOOL CPage8_MasterLevels::OnInitDialog()
{
    CAPage::OnInitDialog();


    // Maik Jurkait [11/15/2006]
    // ------------------------
    // init master-abilities listboxex
    // ------------------------
    for (int t=0;t<NOF_MASTERS;t++)
    {
        mwnd_list[t].InsertColumn(0,_T("Name"));
        mwnd_list[t].InsertColumn(1,_T("Timer"));

        CRect r;
        mwnd_list[t].GetClientRect(r);
        mwnd_list[t].SetColumnWidth(0,r.Width()-40);
        mwnd_list[t].SetColumnWidth(1,40);
        mwnd_list[t].SetExtendedStyle(LVS_EX_FULLROWSELECT);

        mn_tooltip[t] = -1;
    }


    mwnd_selectbutton.SetMaxState(NOF_MASTERS);


    // Maik Jurkait [11/15/2006]
    // ------------------------
    // loading timer image-list
    // ------------------------
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_TIMERS);
    mc_images.Create(12,12,ILC_COLOR24 ,14,4);
    mc_images.Add(&bitmap,RGB(255,255,255));
    bitmap.DeleteObject();

    // Maik Jurkait [11/15/2006]
    // ------------------------
    // init master-level listbox
    // ------------------------
    CRect r;
    mwnd_masterlevels.GetClientRect(r);
    mwnd_masterlevels.InsertColumn(0,_T("ML"));
    mwnd_masterlevels.InsertColumn(1,_T("Quests"));

    mwnd_masterlevels.SetExtendedStyle(LVS_EX_FULLROWSELECT);

    for (int t=1;t<11;t++)
    {
        CString temp;
        temp.Format(_T("%i"),t);

        int idx = mwnd_masterlevels.InsertItem(t,"");
        mwnd_masterlevels.SetCheckbox(idx, 0, 0);
        mwnd_masterlevels.SetItemText(idx,0,temp);
        mwnd_masterlevels.SetItemData(idx,t);

        UpdateMasterLevelsRects(t);
    }

    mwnd_masterlevels.SetColumnWidth(0,32);
    mwnd_masterlevels.SetColumnWidth(1,r.Width()-58);



    // Maik Jurkait [11/15/2006]
    // ------------------------
    // init master-quest listbox
    // ------------------------
    mwnd_masterquests.InsertColumn(0,_T(""));
    mwnd_masterquests.InsertColumn(1,_T("Name"));
    mwnd_masterquests.InsertColumn(2,_T("Type"));

    mwnd_masterquests.SetColumnWidth(0,20);
    mwnd_masterquests.SetColumnWidth(1,99);
    mwnd_masterquests.SetColumnWidth(2,30);

    mwnd_masterquests.SetExtendedStyle(LVS_EX_FULLROWSELECT);

    // apply checkbox
    HDITEM hditem;
    hditem.mask = HDI_IMAGE | HDI_FORMAT;
    mwnd_masterquests.m_HeaderCtrl.GetItem(0, &hditem);
    hditem.fmt |=  HDF_IMAGE;
    hditem.iImage = XHEADERCTRL_UNCHECKED_IMAGE;
    mwnd_masterquests.m_HeaderCtrl.SetItem(0, &hditem);



    OnClassChanged();

    return TRUE;
}



void CPage8_MasterLevels::OnDestroy()
{
    mwnd_masterlevels.DeleteAllItems();
    mwnd_masterquests.DeleteAllItems();

    CAPage::OnDestroy();

}


//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::OnClassChanged()
{
    mb_internal_selection = true;

    for (int t=0;t<NOF_MASTERS;t++)
    {
        CString p = gdbinterface.GetMasterTrack(t);
        mwnd_track_title[t].SetWindowText(p);

        if (GetDocument()->GetMasterPath()==t)
        {
            mwnd_selectbutton.SetWindowText(p);
            mwnd_selectbutton.SetSelection(t);
        }

        // Fill the list boxes
        CStringArray results;
        mwnd_list[t].DeleteAllItems();

        CString target;
        int  timer;

        gdbinterface.SelectMasterTrack(p);
        gdbinterface.GetMasterLevels(results);
        for (int ti=0;ti<results.GetCount();ti++)
        {
            int idx = mwnd_list[t].InsertItem(mwnd_list[t].GetItemCount(),results[ti]);

            gdbinterface.GetMasterLevelInfo(ti+1, target, timer);

            if (timer != 0)
            {
                target.Format(_T("%i"),timer);
                mwnd_list[t].SetItem(idx,1,LVIF_TEXT,target,0,0,0,0,0);
            }
        }
    }

    int level = min(10,GetDocument()->GetMasterLevel());

    mb_internal_selection = false;

    SetToLevel(level+1);
    SetColors();
}


//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::FillQuestList(int level)
{
    level = CLAMP(level,0,10);

    CStringArray ma_names;
    IntArray ma_types;

    gdbinterface.GetMasterQuests(level,ma_names,ma_types);

    mwnd_masterquests.LockWindowUpdate();
    mwnd_masterquests.DeleteAllItems();

    DWORD quest = GetDocument()->GetMasterQuests(level);

    mwnd_masterquests.SetHeaderCheckedState(0,(quest&1)?2:1);

    for (int t=0;t<ma_names.GetCount();t++)
    {
        int idx = mwnd_masterquests.InsertItem(t,"");
        mwnd_masterquests.SetCheckbox(idx, 0, 0!=(quest&(1<<(t+1))));
        mwnd_masterquests.SetItemText(idx,1,ma_names[t]);

        switch(ma_types[t])
        {
            case 0: 
                mwnd_masterquests.SetItemText(idx,2,"Solo");
                mwnd_masterquests.SetItemColors(idx,2,RGB(0,0,0),COLOR_FOR_SOLO);
                break;
            case 1: 
                mwnd_masterquests.SetItemText(idx,2,"Grp");
                mwnd_masterquests.SetItemColors(idx,2,RGB(0,0,0),COLOR_FOR_GROUP);
                break;
            case 2: 
                mwnd_masterquests.SetItemText(idx,2,"BG");
                mwnd_masterquests.SetItemColors(idx,2,RGB(0,0,0),COLOR_FOR_BG);
                break;
        }

        mwnd_masterquests.SetEnabled(idx, !(quest&1));
    }

    mwnd_masterquests.UnlockWindowUpdate();
}



//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    *pResult = 0;

    if (!pNMLV)  return;

    if (pNMLV->iSubItem != 0) return;

    int ml = mwnd_masterlevels.GetCurSel();
    if (ml==CB_ERR) return;
    ml = mwnd_masterlevels.GetItemData(ml);

    bool b_checked = 2==mwnd_masterquests.GetHeaderCheckedState(0);
    GetDocument()->SetMasterQuest(ml,0,b_checked);

    for (int t=0;t<mwnd_masterquests.GetItemCount();t++)
        mwnd_masterquests.SetEnabled(t,!b_checked);

    UpdateMasterLevelsRects(ml);
    SetColors();
}



//////////////////////////////////////////////////////////////////////////
LRESULT CPage8_MasterLevels::OnCheckbox(WPARAM wp, LPARAM lp)
{
    struct_XLISTCTRL_message_checkbox_clicked* message = (struct_XLISTCTRL_message_checkbox_clicked*)lp;

    int nItem = message->n_item;
    int nSubItem = message->n_sub;

    if (wp == IDC_LIST4)
    {

        GetDocument()->SetMasterQuest(nItem+1,0,1==mwnd_masterlevels.GetCheckbox(nItem, 0));

        FillQuestList(nItem+1);
        UpdateMasterLevelsRects(nItem+1);
        SetColors();

        return 0;
    }



    ASSERT(wp == IDC_LIST2);

    int ml = mwnd_masterlevels.GetCurSel();
    if (ml==CB_ERR) return 0;
    ml = mwnd_masterlevels.GetItemData(ml);

    if (nItem >= 0 && nSubItem == 0)
    {
        GetDocument()->SetMasterQuest(ml,nItem+1,1==mwnd_masterquests.GetCheckbox(nItem, 0));
    }

    // Maik Jurkait [11/15/2006]
    // ------------------------
    //  test if all are checked
    // ------------------------
    bool all_checked = true;
    for (int t=0;t<mwnd_masterquests.GetItemCount();t++)
    {
        all_checked &= (1==mwnd_masterquests.GetCheckbox(t, 0));
    }

    if (all_checked)
    {
        GetDocument()->SetMasterQuest(ml,0,true);
        SetColors();
    }

    UpdateMasterLevelsRects(ml);

    return 0;
}




//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::SetColors()
{
    int track = GetDocument()->GetMasterPath();
    int trlevel = GetDocument()->GetMasterLevel();

    for (int tr=0;tr<NOF_MASTERS;tr++)
    {
        for (int t=0;t<mwnd_list[tr].GetItemCount();t++)
        {
            if (tr == track && t < trlevel)
                mwnd_list[tr].SetItemData(t,1);
            else
                mwnd_list[tr].SetItemData(t,0);
        }
    }


    // Description
    CString p = gdbinterface.GetMasterTrack(track);
    gdbinterface.SelectMasterTrack(p);

    mwnd_description.SetWindowText("");
}




//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::OnBnClickedButton1()
{
    GetDocument()->SetMasterPath(mwnd_selectbutton.GetSelection());

    CString p1 = gdbinterface.GetMasterTrack(GetDocument()->GetMasterPath());
    mwnd_selectbutton.SetWindowText(p1);

    SetColors();
}





void CPage8_MasterLevels::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;

    *pResult = CDRF_DODEFAULT;
    switch (lplvcd->nmcd.dwDrawStage)
    {
        case CDDS_PREPAINT:
            *pResult = CDRF_NOTIFYITEMDRAW;          // ask for item notifications.
            break;

        case CDDS_ITEMPREPAINT:
            *pResult = CDRF_NOTIFYSUBITEMDRAW;

            switch (lplvcd->nmcd.lItemlParam)
            {
                case 1:
                    lplvcd->clrTextBk = RGB(196, 196, 255);
                    break;
                case 2:
                    lplvcd->clrTextBk = RGB(212, 212, 212);
                    break;
            }
            break;

        case(CDDS_ITEMPREPAINT | CDDS_SUBITEM):

            if (lplvcd->iSubItem == 1)
            {
                CDC*  pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
                int   nItem = static_cast<int>(lplvcd->nmcd.dwItemSpec);
                CRect rcItem,rcHead;

                int w = -1;
                if (mwnd_list[0].GetSafeHwnd() == pNMHDR->hwndFrom) w = 0;
                if (mwnd_list[1].GetSafeHwnd() == pNMHDR->hwndFrom) w = 1;
                if (mwnd_list[2].GetSafeHwnd() == pNMHDR->hwndFrom) w = 2;


                mwnd_list[w].GetItemRect(nItem, &rcItem, LVIR_BOUNDS);
                mwnd_list[w].GetHeaderCtrl()->GetItemRect(1,rcHead);

                CRect r(rcHead.left,rcItem.top,rcHead.right,rcItem.bottom);

                // get color
                COLORREF col = GetSysColor(COLOR_WINDOW);
                bool b_is_selected = 0!=mwnd_list[w].GetItemState(nItem, LVIS_SELECTED);

                if (lplvcd->nmcd.lItemlParam == 1) { col = b_is_selected?RGB(128, 128, 255):RGB(196, 196, 255); }
                else
                    if (lplvcd->nmcd.lItemlParam == 1) col = RGB(212, 212, 212);
                    else
                        if (b_is_selected)
                        {
                            if (pNMHDR->hwndFrom == ::GetFocus())  col = GetSysColor(COLOR_HIGHLIGHT);
                            else          col = GetSysColor(COLOR_BTNFACE);
                        }

                pDC->FillSolidRect(r,col);


                CString text = mwnd_list[w].GetItemText(nItem,lplvcd->iSubItem);
                int image = _tstoi(text);
                if (image>0)
                    mc_images.Draw(pDC, image-1, r.TopLeft(),ILD_NORMAL);

                *pResult = CDRF_SKIPDEFAULT;
            }
            else
                if (lplvcd->iSubItem == 0 && lplvcd->nmcd.lItemlParam == 1)
                {
                    CDC*  pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
                    int   nItem = static_cast<int>(lplvcd->nmcd.dwItemSpec);

                    int w = -1;
                    if (mwnd_list[0].GetSafeHwnd() == pNMHDR->hwndFrom) w = 0;
                    if (mwnd_list[1].GetSafeHwnd() == pNMHDR->hwndFrom) w = 1;
                    if (mwnd_list[2].GetSafeHwnd() == pNMHDR->hwndFrom) w = 2;

                    // only the selected is handled here
                    if (!mwnd_list[w].GetItemState(nItem, LVIS_SELECTED)) break;


                    CRect rcItem,rcHead;
                    mwnd_list[w].GetItemRect(nItem, &rcItem, LVIR_BOUNDS);
                    mwnd_list[w].GetHeaderCtrl()->GetItemRect(0,rcHead);
                    CRect r(rcHead.left+2,rcItem.top,rcHead.right,rcItem.bottom);

                    pDC->FillSolidRect(r,RGB(128, 128, 255));
                    pDC->SetBkMode(TRANSPARENT);
                    pDC->SetTextColor(RGB(255,255,255));

                    CString str = mwnd_list[w].GetItemText(nItem,0);
                    UINT nFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE; //+++
                    pDC->DrawText(str, &r, nFormat);

                    *pResult = CDRF_SKIPDEFAULT;
                }

            break;
    }
}

//////////////////////////////////////////////////////////////////////////
BOOL CPage8_MasterLevels::GetCellRect(int iRow, int iCol, int nArea, CRect &rect)
{
    if (iCol)
        return mwnd_masterlevels.GetSubItemRect(iRow, iCol, nArea, rect);

    iCol = 1;
    CRect rCol1;
    if (!mwnd_masterlevels.GetSubItemRect(iRow, iCol, nArea, rCol1))
        return FALSE;

    if (!mwnd_masterlevels.GetItemRect(iRow, rect, nArea))
        return FALSE;

    rect.right = rCol1.left;

    return TRUE;
}




//////////////////////////////////////////////////////////////////////////
BOOL CPage8_MasterLevels::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    if (message != LVN_MOUSEMOVE)
        return CAPage::OnWndMsg(message, wParam, lParam, pResult);

    int item = LOWORD(wParam);
    if (item != -1)
    {
        int tr = 0;
        if (HIWORD(wParam)==IDC_LIST1) tr = 1;
        else { ASSERT(HIWORD(wParam)==IDC_LIST3); };

        // Description
        CString p = gdbinterface.GetMasterTrack(tr);

        if (mn_tooltip[tr] != item)
        {
            mn_tooltip[tr] = item;
            gdbinterface.SelectMasterTrack(p);
            //mToolTips.UpdateTipText(&mwnd_list1,gdbinterface.GetMasterDescription(item+1));
            SetTipText(gdbinterface.GetMasterDescription(item+1));
        }
    }

    return CAPage::OnWndMsg(message, wParam, lParam, pResult);
}


//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::SetTipText(CString r)
{
    mwnd_description.SetWindowText(r);
}



//////////////////////////////////////////////////////////////////////////
void CPage8_MasterLevels::OnLvnItemchangedList4(NMHDR *pNMHDR, LRESULT *pResult)
{
    *pResult = 0;
    if (mb_internal_selection) return;

    int sel = mwnd_masterlevels.GetCurSel();
    if (sel == CB_ERR) return;

    int nr = mwnd_masterlevels.GetItemData(sel);
    if (nr<=0) return;

    SetToLevel(nr);
}



void CPage8_MasterLevels::OnLvnItemchangedList3(NMHDR *pNMHDR, LRESULT *pResult)
{
    *pResult = 0;
    if (mb_internal_selection) return;

    POSITION pos = mwnd_list[0].GetFirstSelectedItemPosition();
    if (pos == NULL) return;
    SetToLevel(mwnd_list[1].GetNextSelectedItem(pos)+1);
}


void CPage8_MasterLevels::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
{
    *pResult = 0;
    if (mb_internal_selection) return;

    POSITION pos = mwnd_list[1].GetFirstSelectedItemPosition();
    if (pos == NULL) return;
    SetToLevel(mwnd_list[1].GetNextSelectedItem(pos)+1);
}



void CPage8_MasterLevels::SetToLevel(int nr)
{
    mb_internal_selection = true;

    POSITION pos = mwnd_list[0].GetFirstSelectedItemPosition();
    while (pos)
    {
        int id = mwnd_list[0].GetNextSelectedItem(pos);
        mwnd_list[0].SetItemState(id,0,LVIS_SELECTED);
    }

    pos = mwnd_list[1].GetFirstSelectedItemPosition();
    while (pos)
    {
        int id = mwnd_list[1].GetNextSelectedItem(pos);
        mwnd_list[1].SetItemState(id,0,LVIS_SELECTED);
    }

    mwnd_list[0].SetItemState(nr-1,LVIS_SELECTED,LVIS_SELECTED);
    mwnd_list[1].SetItemState(nr-1,LVIS_SELECTED,LVIS_SELECTED);


    pos = mwnd_masterlevels.GetFirstSelectedItemPosition();
    while (pos)
    {
        int id = mwnd_masterlevels.GetNextSelectedItem(pos);
        mwnd_masterlevels.SetItemState(id,0,LVIS_SELECTED);
    }

    mwnd_masterlevels.SetItemState(nr-1,LVIS_SELECTED,LVIS_SELECTED);
    FillQuestList(nr);

    mb_internal_selection = false;
}
